<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>2048大作战</title>
    <style>
        body {
            font-family: 'Arial', sans-serif;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            margin: 0;
            padding: 20px;
            min-height: 100vh;
            display: flex;
            justify-content: center;
            align-items: center;
        }
        
        .game-container {
            background: white;
            border-radius: 15px;
            padding: 5px;
            box-shadow: 0 10px 30px rgba(0,0,0,0.3);
            max-width: 100%;
            width: 100%;
            text-align: center;
        }
        
        h1 {
            color: #333;
            margin-bottom: 20px;
            font-size: 2.5em;
        }
        
        .game-area {
            display: flex;
            justify-content: space-between;
            align-items: flex-start;
            gap: 20px;
        }
        
        #gameCanvas {
            border: 3px solid #333;
            border-radius: 8px;
            background: #bbada0;
            max-width: 100%;
            height: auto;
            cursor: pointer;
        }
        
        .game-info {
            flex: 1;
            text-align: left;
        }
        
        .score-board {
            background: #f8f9fa;
            border: 2px solid #e9ecef;
            border-radius: 10px;
            padding: 15px;
            margin-bottom: 20px;
        }
        
        .score-board h3 {
            margin: 0 0 10px 0;
            color: #333;
        }
        
        .score-board p {
            margin: 5px 0;
            font-size: 18px;
            font-weight: bold;
        }
        
        .controls {
            background: #f8f9fa;
            border: 2px solid #e9ecef;
            border-radius: 10px;
            padding: 15px;
            margin-bottom: 20px;
        }
        
        .controls h3 {
            margin: 0 0 10px 0;
            color: #333;
        }
        
        .controls p {
            margin: 5px 0;
            font-size: 14px;
        }
        
        .game-buttons {
            display: flex;
            flex-direction: column;
            gap: 10px;
        }
        
        button {
            padding: 12px 24px;
            border: none;
            border-radius: 8px;
            font-size: 16px;
            cursor: pointer;
            transition: all 0.3s ease;
        }
        
        .btn-primary {
            background: #28a745;
            color: white;
        }
        
        .btn-primary:hover {
            background: #218838;
            transform: translateY(-2px);
        }
        
        .btn-secondary {
            background: #6c757d;
            color: white;
        }
        
        .btn-secondary:hover {
            background: #545b62;
            transform: translateY(-2px);
        }
        
        @media (max-width: 768px) {
            .game-container {
                padding: 5px;
            }
            
            .game-area {
                flex-direction: column;
                align-items: center;
            }
            
            .game-info {
                width: 100%;
            }
            
            .score-board, .controls {
                padding: 8px;
                margin-bottom: 10px;
            }
            
            .controls p {
                font-size: 12px;
            }
            
            h1 {
                font-size: 1.8em;
                margin-bottom: 10px;
            }
        }
        
        .mobile-controls {
            display: none;
            margin-top: 15px;
            margin-bottom: 15px;
        }
        
        .control-row {
            display: flex;
            justify-content: center;
            gap: 10px;
            margin: 10px 0;
        }
        
        .control-btn {
            width: 60px;
            height: 60px;
            border-radius: 50%;
            border: 2px solid #333;
            background: #28a745;
            color: white;
            font-size: 24px;
            display: flex;
            align-items: center;
            justify-content: center;
            cursor: pointer;
            user-select: none;
            transition: all 0.2s ease;
            -webkit-tap-highlight-color: transparent;
            touch-action: manipulation;
        }
        
        .control-btn:hover {
            background: #218838;
            transform: translateY(-2px);
            box-shadow: 0 4px 8px rgba(0,0,0,0.2);
        }
        
        .control-btn:active, .control-btn.pressed {
            background: #1e7e34;
            transform: scale(0.95);
            box-shadow: 0 2px 4px rgba(0,0,0,0.2);
        }
        
        @media (max-width: 768px) {
            .mobile-controls {
                display: block;
                margin-top: 10px;
                margin-bottom: 10px;
            }
            
            .control-row {
                margin: 5px 0;
            }
            
            .control-btn {
                width: 50px;
                height: 50px;
                font-size: 20px;
            }
        }
    </style>
</head>
<body>
    <div class="game-container">
        <h1>🎮 2048大作战</h1>
        
        <div class="game-area">
            <canvas id="gameCanvas" width="400" height="400"></canvas>
            
            <div class="mobile-controls">
                <div class="control-row">
                    <div class="control-btn" ontouchstart="handleTouch(event, 'up');" ontouchend="handleTouchEnd(event);" onmousedown="handleMouseDown(event, 'up');" onmouseup="handleMouseUp(event);" onmouseleave="handleMouseUp(event);">↑</div>
                </div>
                <div class="control-row">
                    <div class="control-btn" ontouchstart="handleTouch(event, 'left');" ontouchend="handleTouchEnd(event);" onmousedown="handleMouseDown(event, 'left');" onmouseup="handleMouseUp(event);" onmouseleave="handleMouseUp(event);">←</div>
                    <div class="control-btn" ontouchstart="handleTouch(event, 'down');" ontouchend="handleTouchEnd(event);" onmousedown="handleMouseDown(event, 'down');" onmouseup="handleMouseUp(event);" onmouseleave="handleMouseUp(event);">↓</div>
                    <div class="control-btn" ontouchstart="handleTouch(event, 'right');" ontouchend="handleTouchEnd(event);" onmousedown="handleMouseDown(event, 'right');" onmouseup="handleMouseUp(event);" onmouseleave="handleMouseUp(event);">→</div>
                </div>
            </div>
            
            <div class="game-info">
                <div class="game-buttons">
                    <button class="btn-primary" onclick="startGame()">新游戏</button>
                    <button class="btn-secondary" onclick="resetGame()">重新开始</button>
                </div>
                
                <div class="score-board">
                    <h3>📊 游戏统计</h3>
                    <p>分数: <span id="score">0</span></p>
                    <p>最高分: <span id="highScore">0</span></p>
                    <p>最大数字: <span id="maxTile">0</span></p>
                </div>
                
                <div class="controls">
                    <h3>🎯 操作说明</h3>
                    <p>↑ ↓ ← → : 移动方块</p>
                    <p>相同数字合并</p>
                    <p>目标：合成2048</p>
                    <p>无法移动时游戏结束</p>
                </div>
            </div>
        </div>
    </div>

    <script>
        const canvas = document.getElementById('gameCanvas');
        const ctx = canvas.getContext('2d');
        
        // 游戏常量
        const GRID_SIZE = 4;
        const TILE_SIZE = 90;
        const TILE_MARGIN = 10;
        const BOARD_SIZE = GRID_SIZE * TILE_SIZE + (GRID_SIZE + 1) * TILE_MARGIN;
        
        // 数字颜色映射
        const TILE_COLORS = {
            0: '#cdc1b4',
            2: '#eee4da',
            4: '#ede0c8',
            8: '#f2b179',
            16: '#f59563',
            32: '#f67c5f',
            64: '#f65e3b',
            128: '#edcf72',
            256: '#edcc61',
            512: '#edc850',
            1024: '#edc53f',
            2048: '#edc22e',
            4096: '#3c3a32',
            8192: '#3c3a32'
        };
        
        // 文字颜色映射
        const TEXT_COLORS = {
            0: '#776e65',
            2: '#776e65',
            4: '#776e65',
            8: '#f9f6f2',
            16: '#f9f6f2',
            32: '#f9f6f2',
            64: '#f9f6f2',
            128: '#f9f6f2',
            256: '#f9f6f2',
            512: '#f9f6f2',
            1024: '#f9f6f2',
            2048: '#f9f6f2',
            4096: '#f9f6f2',
            8192: '#f9f6f2'
        };
        
        // 游戏状态
        let board = [];
        let score = 0;
        let highScore = localStorage.getItem('game2048HighScore') || 0;
        let gameWon = false;
        let gameOver = false;
        let touchStartX = 0;
        let touchStartY = 0;
        
        // 初始化游戏
        function initGame() {
            board = Array(GRID_SIZE).fill().map(() => Array(GRID_SIZE).fill(0));
            score = 0;
            gameWon = false;
            gameOver = false;
            
            // 添加两个初始方块
            addNewTile();
            addNewTile();
            
            updateScore();
            updateHighScore();
            updateMaxTile();
            drawGame();
        }
        
        // 添加新方块
        function addNewTile() {
            const emptyCells = [];
            for (let i = 0; i < GRID_SIZE; i++) {
                for (let j = 0; j < GRID_SIZE; j++) {
                    if (board[i][j] === 0) {
                        emptyCells.push({x: i, y: j});
                    }
                }
            }
            
            if (emptyCells.length > 0) {
                const randomCell = emptyCells[Math.floor(Math.random() * emptyCells.length)];
                board[randomCell.x][randomCell.y] = Math.random() < 0.9 ? 2 : 4;
            }
        }
        
        // 绘制游戏
        function drawGame() {
            // 清空画布
            ctx.fillStyle = '#bbada0';
            ctx.fillRect(0, 0, canvas.width, canvas.height);
            
            // 绘制网格
            for (let i = 0; i < GRID_SIZE; i++) {
                for (let j = 0; j < GRID_SIZE; j++) {
                    const x = j * (TILE_SIZE + TILE_MARGIN) + TILE_MARGIN;
                    const y = i * (TILE_SIZE + TILE_MARGIN) + TILE_MARGIN;
                    
                    // 绘制方块背景
                    ctx.fillStyle = TILE_COLORS[board[i][j]] || '#3c3a32';
                    ctx.fillRect(x, y, TILE_SIZE, TILE_SIZE);
                    
                    // 绘制圆角
                    ctx.beginPath();
                    ctx.roundRect(x, y, TILE_SIZE, TILE_SIZE, 6);
                    ctx.fill();
                    
                    // 绘制数字
                    if (board[i][j] !== 0) {
                        ctx.fillStyle = TEXT_COLORS[board[i][j]] || '#f9f6f2';
                        ctx.font = board[i][j] >= 1000 ? 'bold 32px Arial' : 'bold 48px Arial';
                        ctx.textAlign = 'center';
                        ctx.textBaseline = 'middle';
                        ctx.fillText(board[i][j], x + TILE_SIZE / 2, y + TILE_SIZE / 2);
                    }
                }
            }
        }
        
        // 移动方块
        function move(direction) {
            if (gameOver) return false;
            
            let moved = false;
            const newBoard = board.map(row => [...row]);
            
            switch(direction) {
                case 'left':
                    for (let i = 0; i < GRID_SIZE; i++) {
                        const row = newBoard[i].filter(val => val !== 0);
                        for (let j = 0; j < row.length - 1; j++) {
                            if (row[j] === row[j + 1]) {
                                row[j] *= 2;
                                score += row[j];
                                row.splice(j + 1, 1);
                            }
                        }
                        while (row.length < GRID_SIZE) {
                            row.push(0);
                        }
                        newBoard[i] = row;
                    }
                    break;
                    
                case 'right':
                    for (let i = 0; i < GRID_SIZE; i++) {
                        const row = newBoard[i].filter(val => val !== 0);
                        for (let j = row.length - 1; j > 0; j--) {
                            if (row[j] === row[j - 1]) {
                                row[j] *= 2;
                                score += row[j];
                                row.splice(j - 1, 1);
                                j--;
                            }
                        }
                        while (row.length < GRID_SIZE) {
                            row.unshift(0);
                        }
                        newBoard[i] = row;
                    }
                    break;
                    
                case 'up':
                    for (let j = 0; j < GRID_SIZE; j++) {
                        const column = [];
                        for (let i = 0; i < GRID_SIZE; i++) {
                            if (newBoard[i][j] !== 0) {
                                column.push(newBoard[i][j]);
                            }
                        }
                        for (let i = 0; i < column.length - 1; i++) {
                            if (column[i] === column[i + 1]) {
                                column[i] *= 2;
                                score += column[i];
                                column.splice(i + 1, 1);
                            }
                        }
                        while (column.length < GRID_SIZE) {
                            column.push(0);
                        }
                        for (let i = 0; i < GRID_SIZE; i++) {
                            newBoard[i][j] = column[i];
                        }
                    }
                    break;
                    
                case 'down':
                    for (let j = 0; j < GRID_SIZE; j++) {
                        const column = [];
                        for (let i = 0; i < GRID_SIZE; i++) {
                            if (newBoard[i][j] !== 0) {
                                column.push(newBoard[i][j]);
                            }
                        }
                        for (let i = column.length - 1; i > 0; i--) {
                            if (column[i] === column[i - 1]) {
                                column[i] *= 2;
                                score += column[i];
                                column.splice(i - 1, 1);
                                i--;
                            }
                        }
                        while (column.length < GRID_SIZE) {
                            column.unshift(0);
                        }
                        for (let i = 0; i < GRID_SIZE; i++) {
                            newBoard[i][j] = column[i];
                        }
                    }
                    break;
            }
            
            // 检查是否有移动
            for (let i = 0; i < GRID_SIZE; i++) {
                for (let j = 0; j < GRID_SIZE; j++) {
                    if (board[i][j] !== newBoard[i][j]) {
                        moved = true;
                        break;
                    }
                }
            }
            
            if (moved) {
                board = newBoard;
                addNewTile();
                updateScore();
                updateMaxTile();
                
                // 检查是否获胜
                if (!gameWon) {
                    for (let i = 0; i < GRID_SIZE; i++) {
                        for (let j = 0; j < GRID_SIZE; j++) {
                            if (board[i][j] === 2048) {
                                gameWon = true;
                                showMessage('恭喜！你达到了2048！');
                                break;
                            }
                        }
                    }
                }
                
                // 检查游戏是否结束
                if (isGameOver()) {
                    gameOver = true;
                    if (score > highScore) {
                        highScore = score;
                        localStorage.setItem('game2048HighScore', highScore);
                        updateHighScore();
                    }
                    showMessage('游戏结束！');
                }
                
                drawGame();
            }
            
            return moved;
        }
        
        // 检查游戏是否结束
        function isGameOver() {
            // 检查是否有空格
            for (let i = 0; i < GRID_SIZE; i++) {
                for (let j = 0; j < GRID_SIZE; j++) {
                    if (board[i][j] === 0) {
                        return false;
                    }
                }
            }
            
            // 检查是否有相邻的相同数字
            for (let i = 0; i < GRID_SIZE; i++) {
                for (let j = 0; j < GRID_SIZE; j++) {
                    const current = board[i][j];
                    if ((i < GRID_SIZE - 1 && board[i + 1][j] === current) ||
                        (j < GRID_SIZE - 1 && board[i][j + 1] === current)) {
                        return false;
                    }
                }
            }
            
            return true;
        }
        
        // 开始游戏
        function startGame() {
            initGame();
        }
        
        // 重置游戏
        function resetGame() {
            initGame();
        }
        
        // 更新分数显示
        function updateScore() {
            document.getElementById('score').textContent = score;
        }
        
        // 更新最高分显示
        function updateHighScore() {
            document.getElementById('highScore').textContent = highScore;
        }
        
        // 更新最大数字显示
        function updateMaxTile() {
            let maxTile = 0;
            for (let i = 0; i < GRID_SIZE; i++) {
                for (let j = 0; j < GRID_SIZE; j++) {
                    if (board[i][j] > maxTile) {
                        maxTile = board[i][j];
                    }
                }
            }
            document.getElementById('maxTile').textContent = maxTile;
        }
        
        // 显示消息
        function showMessage(text) {
            const messageDiv = document.createElement('div');
            messageDiv.textContent = text;
            messageDiv.style.position = 'fixed';
            messageDiv.style.top = '50%';
            messageDiv.style.left = '50%';
            messageDiv.style.transform = 'translate(-50%, -50%)';
            messageDiv.style.background = 'rgba(0, 0, 0, 0.8)';
            messageDiv.style.color = 'white';
            messageDiv.style.padding = '20px';
            messageDiv.style.borderRadius = '10px';
            messageDiv.style.fontSize = '18px';
            messageDiv.style.zIndex = '1000';
            
            document.body.appendChild(messageDiv);
            
            setTimeout(() => {
                document.body.removeChild(messageDiv);
            }, 2000);
        }
        
        // 键盘控制
        document.addEventListener('keydown', (e) => {
            switch(e.key) {
                case 'ArrowUp':
                    e.preventDefault();
                    move('up');
                    break;
                case 'ArrowDown':
                    e.preventDefault();
                    move('down');
                    break;
                case 'ArrowLeft':
                    e.preventDefault();
                    move('left');
                    break;
                case 'ArrowRight':
                    e.preventDefault();
                    move('right');
                    break;
            }
        });
        
        // 触摸控制
        function handleTouch(event, action) {
            event.preventDefault();
            move(action);
        }
        
        function handleTouchEnd(event) {
            event.preventDefault();
        }
        
        // 鼠标控制（桌面端兼容）
        function handleMouseDown(event, action) {
            event.preventDefault();
            const btn = event.target;
            btn.classList.add('pressed');
            move(action);
        }
        
        function handleMouseUp(event) {
            event.preventDefault();
            const btn = event.target;
            btn.classList.remove('pressed');
        }
        
        // 触摸滑动控制
        canvas.addEventListener('touchstart', (e) => {
            touchStartX = e.touches[0].clientX;
            touchStartY = e.touches[0].clientY;
        });
        
        canvas.addEventListener('touchend', (e) => {
            if (!touchStartX || !touchStartY) return;
            
            const touchEndX = e.changedTouches[0].clientX;
            const touchEndY = e.changedTouches[0].clientY;
            
            const diffX = touchStartX - touchEndX;
            const diffY = touchStartY - touchEndY;
            
            if (Math.abs(diffX) > Math.abs(diffY)) {
                if (diffX > 0) {
                    move('left');
                } else {
                    move('right');
                }
            } else {
                if (diffY > 0) {
                    move('up');
                } else {
                    move('down');
                }
            }
            
            touchStartX = 0;
            touchStartY = 0;
        });
        
        // 初始化游戏
        window.addEventListener('load', initGame);
    </script>
</body>
</html>